﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using grupo2DEWStudio7i.Persistencia;
using grupo2DEWStudio7i.Dominio;
using grupo2DEWStudio7i.Persistencia.ADO;

namespace grupo2DEWStudio7i.Negocio
{
    public class AdministracionServiceImpl : IAdministracionService
    {
        #region Dependencias
        ILocalDAO localDAO = null;
        ISalaDAO salaDAO = null;
        IInstrumentoDAO instrumentoDao = null;
        IClienteDAO clienteDao = null;
        IServicioDAO servicioDAO = null;
        IDetalleSala detalleSalaDAO = null;
        IReservaDAO reservaDAO = null;
        IDetalleReservaDAO detalleReservaDAO = null;
        #endregion

        #region Operaciones de negocio

        public Sala InscribirSala(string nombre, int localCodigo,
             int capacidad, string caracteristicas)
        {
            // Excepción si falta algún dato requerido
            if (nombre == null || localCodigo == 0 ||
                capacidad == 0 || caracteristicas == null)
                throw new DatosInsuficientesException("Faltan datos para crear la sala");
            // Excepción si ya se registró la misma sala (por nombre y código de local)
            Local localExistente = localDAO.Obtener(localCodigo);
            ICollection<Sala> salasEncontradas = salaDAO.ListarXBusqueda(
                null, nombre, null, null, localExistente, null);
            if (salasEncontradas.Count > 0)
                throw new EntidadRepetidaException("La sala ya existe");
            // Creación de la sala
            Sala salaACrear = new Sala();
            salaACrear.Nombre = nombre;
            salaACrear.Local = localExistente;
            salaACrear.Capacidad = capacidad;
            salaACrear.Caracteristicas = caracteristicas;
            return salaDAO.Crear(salaACrear);
        }


        public ICollection<Sala> ListarSalas()
        {
            return salaDAO.ListarTodos();
        }

        public Instrumento RegistrarInstumento(string tipo, string modelo,
             string marca, int añofabri, string caracteristicas, decimal costo)
        {
            // Excepción si falta algún dato requerido
            if (tipo == null || marca == null ||
                modelo == null || añofabri == 0 || costo == 0 || caracteristicas == null)
                throw new DatosInsuficientesException("Datos insuficientes para registrar el Instrumento");
            ICollection<Instrumento> instrumentoEncontrados = instrumentoDao.ListarXTipo(tipo);
            if (instrumentoEncontrados.Count > 0)
                throw new EntidadRepetidaException("El Instrumento ya existe");
            // Creación de la sala
            Instrumento instrumentoACrear = new Instrumento();
            instrumentoACrear.TipoInstru = tipo;
            instrumentoACrear.MarcaInstru = marca;
            instrumentoACrear.ModeloInstru = modelo;
            instrumentoACrear.AñoFabricacion = añofabri;
            instrumentoACrear.Caracteristicas = caracteristicas;
            instrumentoACrear.CostoxHora = costo;
            return instrumentoDao.Crear(instrumentoACrear);
        }

        public Reserva Reservar(int codcliente, int codsala,
           string fecha, string hora, decimal costo, int nrohra)
        {
            // Excepción si falta algún dato requerido
            if (codcliente == null || codsala == null ||
                fecha == null || hora == null || costo == null || nrohra == null)
                throw new DatosInsuficientesException("Faltan datos para crear la reserva");
            // Excepción si ya se registró la misma sala (por nombre y código de local)
            //ICollection<Reserva> reservasEncontradas = reservaDAO.ListarTodos();
            //if (reservasEncontradas.Count > 0)
            //    throw new EntidadRepetidaException("la reserva ya existe");
            // Creación de la sala
            Reserva reservaACrear = new Reserva();

            reservaACrear.Cliente = new Cliente();
            reservaACrear.Cliente.Codigo = codcliente;

            reservaACrear.Sala = new Sala();
            reservaACrear.Sala.Codigo = codsala;

            reservaACrear.Dia = fecha;
            reservaACrear.Hora = hora;
            reservaACrear.CostoTotal = costo;
            reservaACrear.Numero = nrohra;

            return reservaDAO.Crear(reservaACrear);
        }

        public DetalleReserva ReservarDetalle(int CodigoReserva, decimal Costo,
                 int? CodInstrumento, int? CodServicio)
        {
            DetalleReserva detalleReservaACrear = new DetalleReserva();

            detalleReservaACrear.CodigoReserva = CodigoReserva;
            detalleReservaACrear.Costo = Costo;

            if (CodInstrumento.HasValue)
                detalleReservaACrear.Instrumento = new Instrumento() { CodInstrumento = CodInstrumento.Value };
            else
                detalleReservaACrear.Instrumento = null;


            if (CodServicio.HasValue)
                detalleReservaACrear.Servicio = new Servicio() { Codigo = CodServicio.Value };
            else
                detalleReservaACrear.Servicio = null;

            return detalleReservaDAO.Crear(detalleReservaACrear);
        }

        public ICollection<DetalleReserva> ListarReservarDetalle(int CodigoReserva)
        {
            return detalleReservaDAO.ListarxReserva(CodigoReserva);
        }

        public Cliente RegistrarCliente(string nombre, string dni, string clave, string correo, string fecnac)
        {
            // Excepción si falta algún dato requerido
            if (nombre == null || dni == null ||
                fecnac == null || clave == null || correo == null)
                throw new DatosInsuficientesException("Datos insuficientes para registrar el Cliente");
            ICollection<Cliente> clienteEncontrados = clienteDao.ListarBusqueda(null, null, dni, null, correo, null);
            if (clienteEncontrados.Count > 0)
                throw new EntidadRepetidaException("El Cliente ya esta Registrado");
            // Creación de la sala
            Cliente clienteACrear = new Cliente();
            clienteACrear.Nombre = nombre;
            clienteACrear.Dni = dni;
            clienteACrear.FecNac = fecnac;
            clienteACrear.Clave = clave;
            clienteACrear.Correo = correo;
            return clienteDao.Crear(clienteACrear);
        }

        public Servicio RegistrarServicio(string descripcion, int costohora)
        {
            // Excepción si falta algún dato requerido
            if (descripcion == null || costohora == 0)
                throw new DatosInsuficientesException("Datos insuficientes para registrar el Servicio");
            // Excepción si ya se ingresó un servicio con la misma descripcion
            ICollection<Servicio> serviciosEncontrados = servicioDAO.ListarxBusqueda(null, descripcion, null);
            if (serviciosEncontrados.Count > 0)
                throw new EntidadRepetidaException("El Servicio ya esta Registrado");
            // Creación del Servicio OK
            Servicio servicioACrear = new Servicio();
            servicioACrear.Descripcion = descripcion;
            servicioACrear.CostoXhora = costohora;
            return servicioDAO.Crear(servicioACrear);
        }

        public ICollection<Sala> ListarXBusquedaReserva(string nombre, int? codigolocal, int? cantidadInstrumento, string tipoInstrumento, string servicioDescripcion, int? capacidad)
        {
            salaDAO = new SalaDAO();
            ICollection<Sala> lsalas = salaDAO.ListarXBusquedaReserva(nombre, codigolocal, cantidadInstrumento, tipoInstrumento, servicioDescripcion, capacidad);

            if (lsalas.Count < 1)
                throw new NoSeEncontraronDatosException("No se encontraro salas con los criterios ingresados.");

            return lsalas;
        }

        #endregion

        #region Métodos de soporte para entidad Local
        public Local CrearLocal(Local localACrear)
        {
            ICollection<Local> existentes = localDAO.ListarXNombre(localACrear.Nombre);
            if (existentes.Count > 0)
                throw new EntidadRepetidaException("Local ya existente");
            return localDAO.Crear(localACrear);
        }
        public Local ObtenerLocal(int codigo)
        {
            return localDAO.Obtener(codigo);
        }
        public Local ModificarLocal(Local localAModificar)
        {
            return localDAO.Modificar(localAModificar);
        }
        public void EliminarLocal(Local localAEliminar)
        {
            localDAO.Eliminar(localAEliminar);
        }
        public ICollection<Local> ListarLocales()
        {
            return localDAO.ListarTodos();
        }
        public ICollection<Local> ListarLocalesXNombre(string nombre)
        {
            return localDAO.ListarXNombre(nombre);
        }
        #endregion

        #region Métodos de soporte para entidad Sala
        public Sala ObtenerSala(int Codigo)
        {
            return salaDAO.Obtener(Codigo);
        }
        public ICollection<Sala> ListarSalas(string nombre, int? localCodigo,
            int? capacidad, string caracteristicas)
        {
            Local localExistente = null;
            if (localCodigo != null && localCodigo != 0)
                localExistente = localDAO.Obtener(localCodigo.Value);
            return salaDAO.ListarXBusqueda(
                null, nombre, caracteristicas, capacidad, localExistente, null);
        }
        #endregion

        #region Métodos de soporte para entidad Instrumento
        public Instrumento CrearInstrumento(Instrumento instrumentoACrear)
        {
            ICollection<Instrumento> existentes = instrumentoDao.ListarXTipo(instrumentoACrear.TipoInstru);
            if (existentes.Count > 0)
                throw new EntidadRepetidaException("Instrumento ya existente");
            return instrumentoDao.Crear(instrumentoACrear);
        }
        public Instrumento ObtenerInstrumento(int codigo)
        {
            return instrumentoDao.Obtener(codigo);
        }
        public Instrumento ModificarInstrumento(Instrumento instrumentoACrear)
        {
            return instrumentoDao.Modificar(instrumentoACrear);
        }
        public void EliminarInstrumento(Instrumento instrumentoACrear)
        {
            instrumentoDao.Eliminar(instrumentoACrear);
        }
        public ICollection<Instrumento> ListarInstrumento()
        {
            return instrumentoDao.ListarTodos();
        }
        public ICollection<Instrumento> ListarInstrumentosXTipo(string tipo)
        {
            return instrumentoDao.ListarXTipo(tipo);
        }
        public ICollection<Instrumento> ListarInstrumentosXSala(int codigoSala)
        {
            return instrumentoDao.ListarXSala(codigoSala);
        }
        #endregion

        #region Métodos de soporte para entidad Cliente
        public Cliente CrearCliente(Cliente clienteACrear)
        {
            ICollection<Cliente> existentes = clienteDao.ListarBusqueda(null, clienteACrear.Nombre, null, null, null, null);
            if (existentes.Count > 0)
                throw new EntidadRepetidaException("Cliente ya existente");
            return clienteDao.Crear(clienteACrear);
        }
        public Cliente ObtenerCliente(int codigo)
        {
            return clienteDao.Obtener(codigo);
        }
        public Cliente ModificarCliente(Cliente clienteACrear)
        {
            return clienteDao.Modificar(clienteACrear);
        }
        public void EliminarCliente(Cliente clienteACrear)
        {
            clienteDao.Eliminar(clienteACrear);
        }
        public ICollection<Cliente> ListarCliente()
        {
            return clienteDao.ListarTodos();
        }
        public ICollection<Cliente> ListarXBusqueda(int codigo, string nombre, string dni, string fecnac, string clave, string correo)
        {
            return clienteDao.ListarBusqueda(codigo, nombre, dni, fecnac, clave, correo);
        }
        #endregion

        #region Métodos de soporte para entidad Servicio
        public Servicio CrearServicio(Servicio servicioACrear)
        {
            ICollection<Servicio> existentes = servicioDAO.ListarxBusqueda(null, servicioACrear.Descripcion, null);
            if (existentes.Count > 0)
                throw new EntidadRepetidaException("Servicio ya existente");
            return servicioDAO.Crear(servicioACrear);
        }
        public Servicio ObtenerServicio(int codigo)
        {
            return servicioDAO.Obtener(codigo);
        }
        public Servicio ModificarServicio(Servicio servicioAModificar)
        {
            return servicioDAO.Modificar(servicioAModificar);
        }
        public void EliminarServicio(Servicio servicioEliminar)
        {
            servicioDAO.Eliminar(servicioEliminar);
        }
        public ICollection<Servicio> ListarServicio()
        {
            return servicioDAO.ListarTodos();
        }
        public ICollection<Servicio> ListarxBusqueda(int codigo, string descripcion, int costohora)
        {
            return servicioDAO.ListarxBusqueda(codigo, descripcion, costohora);
        }
        public ICollection<Servicio> ListarServiciosXSala(int codigoSala)
        {
            return servicioDAO.ListarxSala(codigoSala);
        }
        #endregion

    }
}